package services

import (
	"fmt"
	"shyxy-net/common/consul"
	"shyxy-net/gateway/http/services/model"
	"sync"
)

type I interface {
	GetService(tag string) (interface{}, error)
}

type ServiceManager struct {
	ConsulAddr      string
	services        map[string]*consul.Server
	discoveryConfig *consul.DiscoveryConfig
	policy          *consul.PolicyConfig
	sync.Mutex
}

func NewServiceManager(consulAddr string, discoveryConfig *consul.DiscoveryConfig) *ServiceManager {
	return &ServiceManager{
		ConsulAddr:      consulAddr,
		services:        make(map[string]*consul.Server),
		discoveryConfig: discoveryConfig,
	}
}

func (sm *ServiceManager) discover(serviceName string) error {
	if sm.services[serviceName] != nil {
		return nil
	}
	var discoveryPolicy *consul.PolicyConfig
	if sm.policy != nil {
		discoveryPolicy = sm.policy
	} else {
		discoveryPolicy = consul.NewPolicy(sm.discoveryConfig.RetryMaxDelay, sm.discoveryConfig.Timeout, sm.discoveryConfig.WaitTime)
		sm.policy = discoveryPolicy
	}
	service, err := sm.discoveryConfig.FindServiceByName(serviceName)
	if err != nil {
		return fmt.Errorf("service %s not found", serviceName)
	}
	ds := consul.NewDiscovery(sm.ConsulAddr, service.Name, discoveryPolicy)
	sm.services[serviceName] = ds
	return nil
}

func (sm *ServiceManager) GetService(tag string) (interface{}, error) {
	sm.Lock()
	defer sm.Unlock()
	if sm.services[tag] != nil {
		return model.New(sm.services[tag]), nil
	}
	if err := sm.discover(tag); err != nil {
		return nil, err
	} else {
		return model.New(sm.services[tag]), nil
	}
}
